package com.maserb.monitor.dataCenter.handler;

import com.maserb.monitor.common.AjaxResult;
import com.maserb.monitor.common.AjaxUtils;
import com.maserb.monitor.common.Func_T;
import com.maserb.monitor.dataCenter.communication.WaveNetPackage;
import com.maserb.monitor.dataCenter.model.*;
import org.apache.commons.collections4.IteratorUtils;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class WaveRequestHandler {
    public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    private Map<WaveRequestKey, List<WaveRequest>> waveRequests = new ConcurrentHashMap<>();

    private ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);

    public void subscribe(WaveRequest request) {
        if (!waveRequests.containsKey(request.getKey())) {
            waveRequests.put(request.getKey(), new CopyOnWriteArrayList<>());
        }

        List<WaveRequest> requests = waveRequests.get(request.getKey());
        requests.add(request);
    }

    public void publish(WaveRequestKey key, WaveNetPackage pack) {
        if (waveRequests.containsKey(key)) {
            WaveResponseResult reponseResult = getResult(pack);
            fixedThreadPool.execute(() -> {
                for (WaveRequest request : waveRequests.get(key)) {
                    if (request.getResponse() != null) {
                        AjaxResult<WaveResponseResult> result = AjaxUtils.process(new Func_T<WaveResponseResult>() {
                            @Override
                            public WaveResponseResult invoke() throws Exception {
                                return reponseResult;
                            }
                        });
                        request.getResponse().setResult(result);
                    }
                }
                waveRequests.remove(key);
            });
        }
    }

    //获取计算后的最大最小值
    private WaveResponseResult getResult(WaveNetPackage pack) {
        WaveResponseResult result = new WaveResponseResult();
        String sampleTime = pack.getEigenValueTime().toDateTime();
        result.setSampleTime(sampleTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(pack.getWaveBeginTime().toDate());
        long minMillis = calendar.getTimeInMillis();
        int interval = (int) ((1 / pack.getSampleFrequence()) * pack.getWaveDataLength() * 1000);
        result.setXMin(dateFormat.format(calendar.getTime()));
        List<Object[]> data = new LinkedList<>();
        int unit = (int) (interval / (pack.getWaveDataLength() - 1));
        calendar.setTimeInMillis(minMillis);
        for (int i = 0; i < pack.getWaveDataLength(); i++) {
            data.add(new Object[]{dateFormat.format(calendar.getTime()), pack.getWaveData()[i]});
            long pMillis = minMillis + (i + 1) * unit;
            calendar.setTimeInMillis(pMillis);
        }
        calendar.setTimeInMillis(minMillis + (pack.getWaveDataLength() - 1) * unit);
        result.setXMax(dateFormat.format(calendar.getTime()));
        result.setWaveData(data);

        List<Float> waveDataCollection = new LinkedList<>();
        float[] wData = pack.getWaveData();
        for (int i = 0; i < wData.length; i++) {
            waveDataCollection.add(wData[i]);
        }
        //取出绝对值最大，以0做对称
        float ymax = Collections.max(waveDataCollection, new Comparator<Float>() {
            @Override
            public int compare(Float o1, Float o2) {
                return Float.compare(Math.abs(o1), Math.abs(o2));
            }
        });
        result.setYMax(Math.abs(ymax));
        result.setYMin(-Math.abs(ymax));

        return result;
    }
}
